<script setup lang="ts">
import type { TreeInstance, TreeNodeData } from 'element-plus'
import type { AppMenu } from '@/apis/system/appMenuApi'
import { onMounted, ref, watch } from 'vue'
import { appMenuApi } from '@/apis/system/appMenuApi'

const { appType } = defineProps<{
  appType?: string
}>()
const menuTree = ref<AppMenu[]>([])
const menuTreeRef = ref<TreeInstance>()

const model = defineModel<number[]>({ })

watch(() => appType, async () => {
  await loadMenuTree()
  model.value = []
})

async function loadMenuTree() {
  if (appType) {
    const list = await appMenuApi.queryTree(appType)
    menuTree.value = list.filter(m => m !== undefined)
  }
  else {
    menuTree.value = []
  }
}

function handleResourceCheckChange(data: AppMenu, checked: boolean) {
  if (checked) {
    const node = menuTreeRef.value?.getNode(data.id!)
    node?.parent?.setChecked(true, false)
  }
  else if (data.children && data.children.length > 0) {
    data.children.forEach(child => menuTreeRef.value?.setChecked(child.id!, checked, false))
  }

  model.value = menuTreeRef.value?.getCheckedKeys() as number[]
}

function treeNodeClass(data: TreeNodeData) {
  if (data.children && data.children.length > 0 && data.path && data.path.length > 0
    && data.children.filter((child: any) => child.children && child.children.length > 0).length === 0
  ) {
    return 'is-penultimate'
  }
  return ''
}

onMounted(loadMenuTree)
</script>

<template>
  <el-tree
    ref="menuTreeRef"
    :props="{ children: 'children', label: 'name', class: treeNodeClass }"
    :data="menuTree"
    :default-checked-keys="model"
    node-key="id"
    show-checkbox
    :check-strictly="true"
    :check-on-click-leaf="false"
    default-expand-all
    class="border border-primary rounded border-solid p-4"
    @check-change="handleResourceCheckChange"
  />
</template>

<style scoped>
:deep(.is-penultimate) > .el-tree-node__children {
  padding-left: 36px;
  --at-apply: flex flex-row flex-wrap;
}

:deep(.is-penultimate) > .el-tree-node__children > div .el-tree-node__content {
  padding-left: 0px !important;
}
</style>
